package cn.suimg.neo4j.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StreamUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 常用工具类
 */
public final class CommonUtil {


    /**
     * Logger
     */
    private static Logger logger = LoggerFactory.getLogger(CommonUtil.class);

    /**
     * 短网址加密用的盐
     */
    private static final String SHORT_LINK_SLAT = "96ebc3110465974570b14869ca7f029e";

    /**
     * 随机生成一个32位的数字字符串
     *
     * @return
     */
    public static String random32S() {
        StringBuilder sb = new StringBuilder();
        Random rand = new Random();
        for (int i = 0; i < 32; i++) {
            sb.append(rand.nextInt(10));
        }
        return sb.toString();
    }

    /**
     * 获取一个随机小写的UUID
     *
     * @return
     */
    public static String randomUUID() {
        return UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
    }

    /**
     * 转换字节数组为文件
     *
     * @param bs
     * @return
     * @throws IOException
     */
    public static File convertByteArray2File(byte[] bs) throws IOException {
        File tempFile = File.createTempFile(String.valueOf(System.currentTimeMillis()), "dat");
        FileCopyUtils.copy(bs, tempFile);
        return tempFile;
    }

    /**
     * 带捕获异常的UrlEncode
     *
     * @param str
     * @return
     */
    public static String urlEncode(String str) {
        try {
            return URLEncoder.encode(str, "utf-8");
        } catch (IOException e) {
            logger.error("url encode error : ", e);
        }
        return null;
    }


    /**
     * 获取ClassPath的文件(针对SpringBoot项目,文件存在于jar之中)
     *
     * @param fileName
     * @return
     * @throws IOException
     */
    public static File getClassPathFile(String fileName) throws IOException {
        File tmpFile = File.createTempFile(String.valueOf(System.currentTimeMillis()), "dat");
        InputStream is = new ClassPathResource(fileName).getInputStream();
        StreamUtils.copy(is, new FileOutputStream(tmpFile));
        return tmpFile;
    }

    public static InputStream getClassPathInputStream(String fileName) throws IOException {
        return new ClassPathResource(fileName).getInputStream();
    }

    /**
     * 获取classpath文件URL
     * @param filename
     * @return
     * @throws IOException
     */
    public static URL getClassPathURL(String filename) throws IOException {
        return new ClassPathResource(filename).getURL();
    }

    /**
     * list去重
     *
     * @param list
     * @param <T>
     * @return
     */
    public static <T> List<T> cleanRepetition(List<T> list) {
        return list.stream().distinct().collect(Collectors.toList());
    }

    /**
     * 对两个值进行比较如果第一个不为空就返回第一个反之返回第二个
     *
     * @param chiefObj
     * @param alternativeObj
     * @param <T>
     * @return
     */
    public static <T> T choiceObject(T chiefObj, T alternativeObj) {
        return chiefObj != null ? chiefObj : alternativeObj;
    }

    /**
     * 适用于方法返回值进行比较，如果使用普通方法在比较之前就会进行运算。
     * @param chiefObj
     * @param alternativeObj
     * @param <T>
     * @return
     */
    public static <T> T choiceObject(Supplier<T> chiefObj,Supplier<T> alternativeObj){
        T result = chiefObj.get();
        return result != null ? result : alternativeObj.get();
    }

    /**
     * 循环指定次数
     *
     * @param max
     * @param consumer
     */
    public static void loop(int max, Consumer<Integer> consumer) {
        for (int i = 0; i < max; i++) {
            consumer.accept(i);
        }
    }


    /**
     * 解决forEach操作动态变量必须标记为final
     * @param list
     * @param consumer
     * @param <T>
     */
    public static <T> void forEach(List<T> list,Consumer<T> consumer){
        for(int i = 0; i < list.size(); i++){
            consumer.accept(list.get(i));
        }
    }

    public static <T> T getListItem(List<T> list,Integer index){
        return list.size() != 0 ? list.get(index) : null;
    }


    /**
     * 生成范围随机数
     * @param min
     * @param max
     * @return
     */
    public static int randomNumber(int min,int max){
        return new Random().nextInt(max) % (max - min + 1) + min;
    }
}
